import sel from '../index.js';
import E from '../direct/effect.js';
var  objs = {};
objs.draw = function () {
    let type = 'id';
    let name = 'name';
    let nodeR = 20;
    function _draw(svgEle) {
      if(!svgEle){
        //自己创建svg宽高在css自己定义
        var svgEle = sel.d3.select('body').append('svg').attr('class','svgEle');
      };

      _draw.pad = svgEle;
      _draw.defs = _draw.pad.append('defs');
      //添加箭头
      _draw.defs.append('marker')
        .attr('id', 'arrow')
        .attr('viewBox', '0 -5 10 10')
        .attr('refX', 10)
        .attr('refY', 0)
        .attr('markerWidth', 5)
        .attr('markerHeight', 5)
        .attr('orient', 'auto')
        .append('path')
        .attr('d','M0,-5L10,0L0,5')
        .attr('fill','#ccc')
      ;
      _draw.contain = _draw.pad.append('g').attr('class','svgAll');
      _draw.graph = _draw.contain.append('g').attr('class','graph');
      _draw.zoom = sel.d3.zoom().on('zoom',()=>_draw.graph.attr('transform', sel.d3.event.transform));
      svgEle.call(_draw.zoom);
      //图例暂时不做
      _draw.legend = _draw.pad.append('g').attr('class','legend').attr('id','legend');
      //各种比例尺
      //节点角度的比例尺
      _draw.degree = sel.d3.scalePoint()
        .padding(0.5)
        .range([0,360])
      ;
      _draw.arc = sel.d3.scalePoint()
        .padding(0.5)
        .range([0,2 * Math.PI])
      ;
      //颜色的id
      _draw.colorId = 0;
      _draw.colorArr = {};
      return _draw;
    };
  /*
  * node的属性更改，唯一的标识，显示内容，半径
  * */
  _draw.changeType = function (t) {
     return t ? (type = t, this) :type
  };
  _draw.changeName = function (n) {
    return n ? (name = n, this) : name
  };
  _draw.changeNodeR = function (r) {
    return r ? (nodeR = r ,this) : nodeR
  };
  /*
   * @param links ，nodes , type 对线上关系进行遍历得到数组，数组对象{target：，source：}
   */
  _draw.bundLines = function (lines){
    let xy = (d)=>{
      return [
        d.x - Math.cos(d.angle) * nodeR,
        d.y - Math.sin(d.angle) * nodeR
      ]
    };
    //根据起始点画出曲线
    let line = sel.d3.line().curve(sel.d3.curveBundle.beta(0.5));
    //插入所有的线段
    let enter = this.graph.selectAll('g.link').data(lines).enter().insert('g','g.node').attr('class','link cell');
    //进行鼠标点击事件的线
    enter.append('path')
    .attr('stroke', 'rgba(255, 255, 255, 0)')
    .attr('stroke-width', 6)
    .attr('fill', 'none')
    .attr('class', 'for-mouse')
    ;
    //展示线
    enter.append('path')
    .attr('stroke',function (d) {
      return d.source.classColor || 'lightgray';
    })
    .attr('fill', 'none')
    .attr('class', 'line')
    .attr('marker-end', 'url(#arrow)')
    .attr('d', 'M0 0L0 0')
    ;
    //所有线段进行路径绘画
    this.graph.selectAll('g.link').each(function (d) {
      let t = sel.d3.select(this);
      let lineD = line([xy(d.source), [0,0], xy(d.target)]);
      t.selectAll('path').attr('d',function (d) {
        // d.path = lineD;
        return lineD;
      });
    })
  };
  _draw.drawLines = function (lines,nodes) {
    let arr = [];
    for(let i = 0 ; i < lines.length; i ++){
      let obj = {};
      for(let j = 0 ; j < nodes.length; j++ ) {
        if(lines[i].target == nodes[j][type]){
          obj.target = nodes[j];
        }
        if(lines[i].source == nodes[j][type]){
          obj.source = nodes[j];
        }

      };
      arr.push(obj);
    };
    if(arr.length == 0){
      console.log('没有找到线');
    }else {
      this.bundLines(arr);
    }


  };
  _draw.drawNodes = function (nodes,r) {
    this.setDomain(nodes);
    let that = this;
    let width = sel.d3.select('svg').style('width').replace('px',"");
    let height = sel.d3.select('svg').style('height').replace('px',"");
    this.transformGraph(width,height);
    let enter = this.graph.selectAll('g.cell').data(nodes).enter();
    let node = enter.append('g')
        .attr('class','node cell')
        .style('cursor','poniter')
        .on('mouseenter',function (d) {
          that.force(d);
        })
        .on('mouseout',d=>{
          this.cancelFocus();
        })
      .attr('transform',d=>{
        d.angle = this.arc(d[type]);
        d.x = Math.cos(d.angle) * r ;
        d.y = Math.sin(d.angle) * r ;
        let degree = this.degree(d[type]);
        if (degree > 90 && degree < 270) {
          degree += 180
        }
        return  "translate(" + d.x +' '+ d.y +") rotate("+degree+")"
      });
    node
      .append('text')
      .attr('text-anchor', function (d) {
        if(_draw.degree(d[type]) > 90 && _draw.degree(d[type]) < 270){
          return 'end'

        }
        return 'start'

      })
      .attr('dominant-baseline', 'middle')
      .text(function (d) {
        return d[name]
      })
    ;

    sel.d3.selectAll('g.node').each(function () {
      sel.d3.select(this).append('circle')
      .attr('fill',function (d) {
        var c = _draw.color( d.classColor || null);
        var url = 'url(#'+c+')';
        return url;
      })
      .attr('r',nodeR)
      ;

    });

  };
  _draw.bund = function (lines,nodes,r) {
    _draw.drawNodes(nodes,r);
    _draw.drawLines(lines,nodes);
  };
  /*
  * 根据宽高移动画布
  * */
  _draw.transformGraph = function (w,h) {
    w = parseInt(w);
    h = parseInt(h);
    let objs = sel.d3.zoomTransform(this.pad);
    objs.x = w/2;
    objs.y = h/2;
    objs.k = 1;
    this.zoom.transform(this.graph,objs);
  };
    //绘制颜色
  //自动渐变色color可以为数组，可以为rgb（）,
  _draw.color = function (color) {
      if(!color){
        return this.drawColor();
      }
      if (this.colorArr[color]){return this.colorArr[color]}
      if(/^rgba/.test(color)){
        color = color.replace('rgba(','').replace(')','').split(',');
      }else if(/^rgb/.test(color)) {
        color = color.replace('rgb(','').replace(')','').split(',');
      }
      if(color.constructor === Array){
        color = sel.d3.rgb(color[0],color[1],color[2]);
        return this.drawColor(color);
      }else {
        console.log('颜色参数错误')
      }
    };
    //渐变色的生成器
  _draw.drawColor = function (color) {
     if(!color){
       let color = "rgb(51, 204, 204)";
     }
     if (this.colorArr[color]){return this.colorArr[color]}
     this.colorId++;
     let id = 'colorScale' + this.colorId;
     this.colorArr[color] = id;
     sel.d3.select('#'+id).empty();
     //绘制渐变色
     let svgRadil = this.defs.append('radialGradient')
             .attr('id',id)
             .attr('cx','50%')
             .attr('cy','50%')
             .attr('fx','50%')
             .attr('r','50%')
     ;
     svgRadil.append('stop')
       .attr('offset','0%')
       .style('stop-color',"#fff")
       .style('stop-opacity','0')
     ;
     svgRadil.append('stop')
       .attr('offset','100%')
       .style('stop-color',color)
       .style('stop-opacity','1')
     ;
    return id;
  };
    //定义域的绑定
  _draw.setDomain = function (nodes) {
  this.degree.domain(nodes.map(d => d[type]));
  this.arc.domain(nodes.map(d => d[type]));
};

  //新添加一些特效
  _draw.force = function (nd) {
    this.lightEffect && this.lightEffect.clear();
    //此处调用effect的时候进行参数初始化
    this.lightEffect = E.light().radius(3).speed(100).color(function (d) {
      return d.source.classColor || 'green'
    });
    //对球做一些样式
    this.graph.selectAll('g.cell')
      .classed('focused',false)
      .transition('focus')
      .duration(200)
      .style('opacity','0.2')
    ;
    this.graph.selectAll('g.link').each(function () {
      sel.d3.select(this).selectAll('path.line').attr('stroke-width',1);
    });

    ;
    //判断是否重复
    let name = {};
    let links = this.graph.selectAll('g.link')
          .filter(function (d) {
            if(d.source[type] == nd[type] || d.target[type] == nd[type]){
              name[d.source[type]] = true;
              name[d.target[type]] = true;
              return true
            }else {
              return false
            }
          });

    links.selectAll('path.line').call(this.lightEffect);
    links
      .classed('focused', true)
      .interrupt('focus')
      .style('opacity', 1)
      .selectAll('path.line')
      .attr('stroke-width', 2)
    ;
    let nodes = this.graph.selectAll('g.node')
          .filter(function (d) {
            return name[d[type]]
        })
    ;
    nodes
        .interrupt('focus')
        .style('opacity', 1)
    ;


  };

//新特效的清除
  _draw.cancelFocus = function () {
    this.lightEffect && this.lightEffect.clear();
    this.graph.selectAll('g.cell')
    .classed('focused', false)
    .classed('focused-origin', false)
    .interrupt('focus')
    .transition('focus')
    .ease(sel.d3.easeLinear)
    .style('opacity', 1)
    .selectAll('path.line')
    .attr('stroke-width', 1)
    ;
  };


  return _draw;
};//完毕

export default {
  init : function () {
    sel.app.factory('bund',function () {
      return objs;
    });
  }
}